package com.hsh.tools.handler;

import com.hsh.utils.vo.Response;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

@ControllerAdvice
//@RestController
public class GlobalExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());

    /**
     * 异常已被全局捕获
     */
    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public Response error(Throwable e) {
        e.printStackTrace();
        logger.error(e.getMessage());
        return Response.fail("异常已被全局捕获 --> " + e.getMessage());
    }

    /**
     * 算数异常
     */
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public Response error(ArithmeticException e) {
        e.printStackTrace();
        logger.error(e.getMessage());
        return Response.fail("算数异常 --> " + e.getMessage());
    }

    /**
     * 空指针异常
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public Response error(NullPointerException e) {
        e.printStackTrace();
        logger.error(e.getMessage());
        return Response.fail("空指针异常 --> " + e.getMessage());
    }

    /**
     * 认证异常
     */
    @ExceptionHandler(AuthenticationException.class)
    @ResponseBody
    public Response error(AuthenticationException e) {
        e.printStackTrace();
        logger.error(e.getMessage());
//        return Response.fail(e.getMessage());
        return Response.fail(e.getMessage());
    }

    /**
     * 没有权限异常
     */
    @ExceptionHandler(UnauthorizedException.class)
    @ResponseBody
    public Response error(UnauthorizedException e) {
        e.printStackTrace();
        logger.error(e.getMessage());
//        return Response.fail("您没有权限访问，请联系相关人员！");
        return Response.fail(e.getMessage());
    }


    /**
     * 自定义异常捕获
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public Response error(BusinessException e) {
        e.printStackTrace();
        logger.error(e.getErrMsg());
        return Response.fail(e.getErrMsg());
    }

    //处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Response BindExceptionHandler(BindException e) {
        System.out.println("~~~~~11");
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return Response.fail(message);
    }

    //处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public Response ConstraintViolationExceptionHandler(ConstraintViolationException e) {
        System.out.println("~~~~~22");
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
        return Response.fail(message);
    }

    //处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Response MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        System.out.println("~~~~~33");
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return Response.fail(message);
    }
}
